﻿using Zen4SyncPOCO.ClientTestSessionDescriptorHandler;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Zen4SyncPOCO.POCO.Admin;
using System.Xml.Linq;
using Microsoft.XmlDiffPatch;
using System.IO;
using System.Xml;
using System.Text;

namespace Zen4SyncPOCO.Test
{
    /// <summary>
    /// Test class for IClientTestSessionDescriptorHandlerTest.
    /// 
    /// The tests use XmlDiffPatch tool from Microsoft to compare XML files :
    /// http://msdn.microsoft.com/en-us/library/aa302294.aspx
    /// 
    /// The Test Class deploys the content of the TestData\ project directory
    /// into a TestData\ directory under the test deployment directory.
    /// </summary>
    [TestClass()]
    [DeploymentItem(@"TestData\", @"TestData")]
    public class IClientTestSessionDescriptorHandlerTest
    {
        /// <summary>
        /// Complete file name of the reference ClientTestSessionDescriptorWithOverridingData.xml file.
        /// 
        /// This file name refers to the deployed ClientTestSessionDescriptorWithOverridingData.xml
        /// (the one copied in the test deployment directory because of the DeploymentItem attribute
        /// on this Test Class).
        /// 
        /// This file is the ClientTestSessionDescriptor WITH overriding data in activity contexts,
        /// which means it's the equivalent of a ClientTestSessionDescriptor just created from a ClientSession
        /// POCO which contained overriding data.
        /// </summary>
        private string ReferenceClientTestSessionDescriptorWithOverridingData
        {
            get
            {
                return Path.Combine(TestContext.DeploymentDirectory, @"TestData\ClientTestSessionDescriptorWithOverridingData.xml");
            }
        }

        /// <summary>
        /// Complete file name of the reference ClientTestSessionDescriptorWithoutOverridingData.xml file.
        /// 
        /// This file is the ClientTestSessionDescriptor WITHOUT overriding data in activity contexts,
        /// which means it's the equivalent of a ClientTestSessionDescriptor just created from a ClientSession
        /// POCO which did not contain any overriding data.
        /// </summary>
        private string ReferenceClientTestSessionDescriptorWithoutOverridingData
        {
            get
            {
                return Path.Combine(TestContext.DeploymentDirectory, @"TestData\ClientTestSessionDescriptorWithoutOverridingData.xml");
            }
        }


        private TestContext testContextInstance;

        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        internal virtual IClientTestSessionDescriptorHandler CreateIClientTestSessionDescriptorHandler()
        {
            IClientTestSessionDescriptorHandler target = ClientTestSessionDescriptorHandlerFactory.Instance;
            return target;
        }

        /// <summary>
        /// CreateClientTestSessionDescriptor test :
        ///
        /// TestData\ClientTestSessionDescriptor.xml file is the ClientTestSessionDescriptor we want to reproduce.
        /// 
        /// ClientSession property of ClientSessionProvider class returns a ClientSession object which is equivalent
        /// to the one described in TestData\ClientTestSessionDescriptor.xml.
        /// 
        /// We create a ClientTestSessionDescriptor from the ClientSession object. If this ClientTestSessionDescriptor
        /// is the same as the TestData\ClientTestSessionDescriptor.xml file then the test passes.
        /// </summary>
        [TestMethod()]
        public void CreateClientTestSessionDescriptorTest()
        {
            IClientTestSessionDescriptorHandler target = CreateIClientTestSessionDescriptorHandler();

            ClientSessionProvider provider = new ClientSessionProvider(TestContext.TestDeploymentDir);

            // Create the ClientTestSessionDescriptor from a ClientSession object
            XElement actual = target.CreateClientTestSessionDescriptor(provider.ClientSession);

            // Save it on disk because the XmlDiff tool compares files
            string actualFileName = Path.Combine(TestContext.DeploymentDirectory, "ClientTestSessionDescriptor_created.xml");
            actual.Save(actualFileName);

            // Compare the reference ClientTestSessionDescriptor and the one just created, ignoring comments and whitespaces
            // If the comparison fails, take a look at the content of fileDifferences StringBuilder
            XmlDiff xmlDiff = new XmlDiff(XmlDiffOptions.IgnoreComments | XmlDiffOptions.IgnoreWhitespace);
            StringBuilder fileDifferences = new StringBuilder();
            XmlWriter fileDifferencesWriter = XmlWriter.Create(fileDifferences);
            bool filesAreIdentical = xmlDiff.Compare(ReferenceClientTestSessionDescriptorWithOverridingData, actualFileName, false, fileDifferencesWriter);

            Assert.IsTrue(filesAreIdentical);
        }

        /// <summary>
        /// ReadClientTestSessionDescriptor test :
        /// 
        /// Convert the reference ClientTestSessionDescriptor.xml WITH overriding data file into a ClientSession.
        /// This conversion should take the overriding data into account.
        /// 
        /// Then turn this ClientSession back into its ClientTestSessionDescriptor representation : no overriding data
        /// in the XML because they've been taken into account by the ClientTestSessionDescriptor reader.
        /// 
        /// Compare the XML representation of the ClientSession object (without overriding data) with the reference
        /// ClientTestSessionDescriptor.xml WITHOUT overriding data file.
        /// If the 2 files are identical, then the test passes.
        /// </summary>
        [TestMethod()]
        public void ReadClientTestSessionDescriptorTest()
        {
            IClientTestSessionDescriptorHandler target = CreateIClientTestSessionDescriptorHandler();

            // Read the reference ClientTestSessionDescriptor.xml WITH overriding data and turn it into a ClientSession object
            // So the ClientSession object properties must take into account the overriding data
            XElement referenceCTSD = XElement.Load(ReferenceClientTestSessionDescriptorWithOverridingData);
            ClientSession parsedClientSession = target.ReadClientTestSessionDescriptor(referenceCTSD);

            // Turn this ClientSession object back into its XML representation
            // This XML representation must not have overriding data since they've been taken into account by the reader of the ClientTestSessionDescriptor.xml
            XElement rewrittenCTSD = target.CreateClientTestSessionDescriptor(parsedClientSession);

            // Save the XML representation on disk
            string rewrittenCTSDFileName = Path.Combine(TestContext.DeploymentDirectory, "ClientTestSessionDescriptor_rewritten.xml");
            rewrittenCTSD.Save(rewrittenCTSDFileName);

            // Compare the ClientTestSessionDescriptor WITHOUT overriding data and the one rewritten from the ClientSession object
            // If the comparison fails, take a look at the content of fileDifferences StringBuilder
            XmlDiff xmlDiff = new XmlDiff(XmlDiffOptions.IgnoreComments | XmlDiffOptions.IgnoreWhitespace);
            StringBuilder fileDifferences = new StringBuilder();
            XmlWriter fileDifferencesWriter = XmlWriter.Create(fileDifferences);
            bool filesAreIdentical = xmlDiff.Compare(ReferenceClientTestSessionDescriptorWithoutOverridingData, rewrittenCTSDFileName, false, fileDifferencesWriter);

            Assert.IsTrue(filesAreIdentical);
        }
    }
}
